Dev - #5
Open
recepteksi wants to merge 40 commits into
Open
Conversation
Problem 1: Objects couldn't be dropped everywhere during drag - Root cause: ARCore hit test only updates position on valid plane surfaces - Fix: Keep last valid position when hit test fails, object stays in place - Added lastValidDragPosition to track successful drag positions Problem 2: Trash zone deletion not working reliably - Root cause: onDragUpdate only called when currentObj found in placedObjects - Fix: Always call onDragUpdate even if object not found (use default position) - Added final trash zone check in onDragEnd to ensure deletion works Fixes: fix-drag-drop-position, fix-trash-zone-delete Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added isOverTrashZone() helper function that checks both X (right side) and Y (bottom) coordinates - Fixed trash zone hit detection to properly detect when object is dragged to bottom-right corner - Updated onDragMove and onDragEnd to use the new isOverTrashZone() function - Constants: TRASH_ZONE_SIZE_DP=80, TRASH_ZONE_MARGIN_DP=16 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fixed magic strings in TrashZone (now uses localized strings) - Removed unused 'progress' variable - Added release_to_delete and drag_to_delete strings (EN and TR) - Improved drag movement with camera ray projection fallback - Objects can now be moved to areas without detected planes - Uses camera's view matrix to project movement Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause: Camera ray projection fallback was using absolute screen coordinates instead of delta movement, causing erratic object positioning. Solution: - Track last screen position (dragLastScreenX/Y) for delta calculation - Use screen delta movement instead of absolute normalized coordinates - Project finger movement to world XZ plane using camera vectors - Apply delta to current position instead of recalculating from scratch - Scale pixel-to-world conversion based on object distance from camera Also includes style improvements to TrashZone: - Add semi-transparent background - Add subtle shadow effect - Add subtle border - Center text properly - Increase size for better text fit Fixes: drag-everywhere-bug Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add semi-transparent background (alpha 0.7 normal, 0.85 hovered) - Add subtle shadow effect for better visibility - Add subtle border for definition - Center text with TextAlign.Center and fillMaxWidth - Increase size to 100x90dp for better text fit - Add fillMaxSize to Column for proper centering Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause: isOverTrashZone() was using incorrect dimensions (80dp x 80dp) that didn't match the actual TrashZone component (100dp x 90dp). Solution: Updated trash zone detection to use the correct dimensions: - trashZoneWidth = 100.dp (matches component's width) - trashZoneHeight = 90.dp (matches component's height) - trashZonePadding = 16.dp The detection area now correctly matches the visual trash zone position, enabling reliable drag-to-delete functionality. Fixes: trash-zone-delete-bug Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added ObjectThumbnail composable for displaying 3D object previews - Updated ObjectListItem in ARScreen with thumbnail support - Updated ObjectListItem in ObjectListScreen with thumbnail support - Uses placeholder icon (ViewInAr) based on model type - Thumbnails display in styled boxes with rounded corners - Selected state shows highlighted background Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added Koin dependencies (koin-core, koin-android, koin-compose) - Created DI modules: dataModule, applicationModule, presentationModule - Created platform-specific modules for Android and iOS data sources - Updated MainActivity to initialize Koin - Updated App.kt to use koinInject() for ViewModels - Simplified dependency wiring through DI container Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added CapturedPhoto model in domain layer - Created MediaRepository interface - Implemented CapturePhotoUseCase - Added Android MediaRepositoryImpl with MediaStore API - Added capture button to AR screen (camera icon) - Implemented PixelCopy-based AR view capture - Integrated with Koin DI - Added iOS placeholder implementation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add CapturedVideo domain model to CapturedMedia.kt - Extend MediaRepository interface with video recording methods - Create RecordVideoUseCase for recording state management - Update Android MediaRepositoryImpl with video recording support - Add RecordingState sealed class to ARViewModel - Add startRecording/stopRecording/toggleRecording functions - Update ARScreen with VideoRecordButton and RecordingIndicator - Add iOS MediaRepositoryIOSImpl stub implementation - Update DI modules with RecordVideoUseCase - Fix GalleryViewModel coroutine scope issue - Fix iOS MainViewController to use Koin injection Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added ObjectGalleryScreen with grid layout (2-column LazyVerticalGrid) - Created ObjectGalleryCard component with visual previews - Implemented model type badges (GLB/GLTF/USDZ/OBJ) - Added search/filter functionality for objects - Added empty state with import CTA - Added no-results state for search - Updated App.kt navigation with Screen.ObjectGallery - Added i18n strings (EN/TR) for gallery Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added Kover plugin for test coverage reporting - Configured HTML and XML report generation - Added exclusion filters for generated code - Reports generated at build/reports/kover/ Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add VideoRecorder class for ARSceneView video capture using MediaRecorder - Add camera-style controls: CameraStyleRecordButton, RecordingTimerDisplay - Add CameraControlsBar with photo, record, and gallery buttons - Add RecordingBorderGlow effect during recording - Add recording duration timer in ARViewModel - Update ARScreen with new camera-style controls layout - Connect VideoRecorder to MediaRepository via callbacks Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
UI Changes: - Move selected object indicator from bottom to top-left - Redesign camera controls bar with clean centered layout - Add semi-transparent background to camera controls - Fix overlapping elements in AR screen Video Recording Fix: - Connect VideoRecorder directly to MediaRepository via Koin - Register recording callbacks when ARSceneView is ready - Clear callbacks properly on dispose Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add ModelPreviewThumbnail expect/actual for cross-platform support - Android: SceneView-based 3D rendering with auto-rotation - iOS: Placeholder icon fallback - Integrate into ObjectGalleryScreen - Handle loading states and errors gracefully Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove environmentLoader to avoid missing HDR file crash - Simplify Scene setup to use default environment - Improve error handling in model loading Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
3D SceneView preview causing stability issues. Temporarily disabled until resolved. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Rewrite VideoRecorder with MediaCodec + MediaMuxer approach - Add thread safety with CountDownLatch synchronization - Register GalleryViewModel in Koin AppModule - Add gallery use case registrations (GetPhotos, GetVideos, DeletePhoto, DeleteVideo) - Fix GalleryScreen callbacks in App.kt navigation - Add MediaItem import for gallery functionality - Fix capturePhoto → requestCapture method call Video recording now properly: - Handles cross-thread calls from IO dispatcher - Uses InputSurface from MediaCodec instead of Canvas drawing - Caps resolution at 1920x1080 with aspect ratio preservation - Uses 8 Mbps bitrate for efficient encoding Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause: startKoin was called unconditionally in onCreate, causing KoinApplicationAlreadyStartedException when Activity recreates (e.g., on configuration change, back navigation). Solution: Check GlobalContext.getOrNull() before initializing Koin to skip initialization if already started. Fixes: KAN-1 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ARViewModel was not receiving CapturePhotoUseCase due to positional parameter injection. Changed to named parameter injection to ensure proper dependency resolution. Fixes: KAN-4 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace SpaceEvenly layout with weighted sections - Use Box with weight(1f) for left and right sections - Center record button uses fixed size (80dp) without weight - Gallery button aligned to end of left section - Photo capture button aligned to start of right section - Remove unused placeholder boxes - Clean up unused imports Fixes: KAN-7 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause: GalleryViewModel was being eagerly injected at App() composition time, causing loadMedia() to run immediately even before user navigates to Gallery screen. This triggered premature MediaRepository access. Solution: Move GalleryViewModel injection inside the Screen.Gallery when branch, so it only initializes when user actually navigates to the Gallery screen. Fixes: KAN-6 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Android: Fix SceneView crash with 3 root causes resolved: - Remove Dispatchers.IO dispatch (Filament must finalize on main thread) - Add key(modelPath) to prevent EGL context exhaustion in LazyGrid - Add DisposableEffect for deterministic GPU resource cleanup iOS: Implement platform-native preview: - USDZ: SCNView (SceneKit) via UIKitView with SCNAction auto-rotation - GLB/GLTF: QLThumbnailGenerator (QuickLook) async thumbnail - Fallback: placeholder icon for unsupported formats Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract pure logic into ModelPreviewThumbnailHelper for testability: - resolvePreviewStrategy: iOS extension routing (usdz/glb/placeholder) - resolveInitialAndroidState: file existence guard - resolveAndroidStateAfterLoad: post-load state machine - extractExtension: shared path utility 27 tests with Given-When-Then pattern using kotlin.test Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
C-1: Wire ModelPreviewThumbnailHelper into actual implementations - Android: resolveInitialAndroidState() + resolveAndroidStateAfterLoad() - iOS: resolvePreviewStrategy() replaces inline when block C-2: Guard GLBThumbnailPreview against use-after-dispose - DisposableEffect nulls imageViewRef on disposal M-1: Replace 8 wildcard imports with explicit symbols in iOS file Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause: rememberEngine() created a new Filament Engine per thumbnail composable in LazyVerticalGrid. Filament has a hard limit of ~1 engine instances; creating one per visible grid cell caused immediate native crash. Fix: Introduce ModelPreviewEngineProvider with singleton Engine pattern: - commonMain: expect interface with lifecycle-aware engine sharing - androidMain: activity-scoped Engine singleton via rememberUpdatedState - iosMain: no-op (SceneView not used; SCNView manages its own context) ObjectGalleryScreen updated to provide engine via CompositionLocal. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add linkerOpts("-framework", "SceneKit") in build.gradle.kts
- Remove QLThumbnailGenerator usage (not available in Kotlin/Native cinterop)
- GLB format falls back to placeholder on iOS (primary iOS format is USDZ)
- Fix explicit Icon import replacing fully-qualified call
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove orphaned linkerOpts("-framework", "QuickLook") — QuickLook
is no longer used after QLThumbnailGenerator removal
- Update stale KDoc for PreviewStrategy.GLB_THUMBNAIL to reflect
placeholder behaviour instead of QLThumbnailGenerator
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add explicit engine.destroy() + modelLoader.destroy() in DisposableEffect to prevent Filament GL resource leaks on repeated gallery open/close - Narrow ModelPreviewEngineProvider scope to wrap only ObjectGalleryGrid instead of the entire screen (dialogs/snackbars no longer inside provider) - Make ObjectGalleryCard private (only used within ObjectGalleryScreen) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rag-delete - Remove explicit arSceneView?.destroy() in DisposableEffect — SceneView's onDetachedFromWindow already destroys; double-destroy caused NPE in CameraNode - Revert worldToScreen to require TrackingState.TRACKING — relaxed check caused false positive node hits that blocked model placement - Guard onFrame animation loop with isAttachedToWindow to prevent NPE on destroy - Add PhotoThumbnail expect/actual for persistent URI-based thumbnail display - Load last captured photo path from GetPhotosUseCase on startup for persistence - Fix GalleryScreen LazyVerticalGrid duplicate key crash (photo vs video IDs collide) - Hide CameraControlsBar during drag so trash zone receives touch events - Add GLB animation playback via onFrame + Filament Animator API - Fix GalleryViewModel scope (factory → single) to prevent multiple VM instances Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Gallery crash: remove double-destroy in DisposableEffect (NPE in CameraNode) - Model placement regression: restore TrackingState.TRACKING check in worldToScreen - Thumbnail persistence: URI-based PhotoThumbnail loaded from GetPhotosUseCase on startup - Animated GLB models: drive Filament Animator via onFrame callback - Drag-to-delete: hide CameraControlsBar during drag so trash zone gets touch events - GalleryScreen crash: prefix photo/video keys in LazyVerticalGrid to avoid duplicate keys
recepteksi
force-pushed
the
dev
branch
2 times, most recently
from
April 17, 2026 18:54
b640132 to
26eba64
Compare
Changed `if (bitmap != null) { Image(bitmap = bitmap!!) }` to
`bitmap?.let { Image(bitmap = it, ...) }` to prevent NPE from force-unwrap.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…handling - Handle content:// URI inputStream returning null explicitly - Handle file:// prefix stripping for absolute paths - Add file existence check before decodeFile - Catch IllegalArgumentException for malformed images - Catch SecurityException for permission issues - Add comprehensive logging for debugging Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.